package com.zjw.zy.base.special;

import android.os.Looper;

import androidx.annotation.NonNull;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleEventObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Observer;

import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author ：zhong.jw
 * @date ：Created in 2022/5/19 11:26
 * <p>
 * <p>
 * observer时不会读取旧数据的liveData:
 * <p>
 * mvp数据倒灌的本质是Fragment.onViewCreate和Fragment.onDestroyView时重复注册和移除observer，就会导致
 * observer时又读取了liveData中原本post过的数据，那么只要在特定功能下采用此FutureLiveData(此名为注册后只读取未来发布的值),
 * 即可解决数据倒灌问题。
 */
public class FutureLiveData<T> extends MutableLiveData<T> {

    private final AtomicInteger mGlobalVersion = new AtomicInteger(0);

    private final AtomicBoolean mForceNotifyFlag = new AtomicBoolean(false);

    private LifecycleEventObserver mLifecycleEventObserver = null;

    public FutureLiveData(T t) {
        super(t);
    }

    public FutureLiveData() {
        super();
    }

    @Override
    public void setValue(T value) {
        mGlobalVersion.incrementAndGet();
        super.setValue(value);
    }

    /**
     * 发布值，之前注册的观察者才可收到；
     */
    @Override
    public void postValue(T value) {
        observeFutureStatus();
        if (Looper.getMainLooper() == Looper.myLooper()) {
            this.setValue(value);
        } else {
            super.postValue(value);
        }
    }

    @Override
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        super.observe(owner, new ObserverWrap(observer, mGlobalVersion.get()));
    }

    /**
     * 当Destroy后，恢复postValue状态;
     */
    public void observeFutureWhenDestroy(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        mLifecycleEventObserver = (source, event) -> {
            if (event == Lifecycle.Event.ON_DESTROY) {
                FutureLiveData.this.observeFutureStatus();
                owner.getLifecycle().removeObserver(mLifecycleEventObserver);
                mLifecycleEventObserver = null;
            }
        };
        owner.getLifecycle().addObserver(mLifecycleEventObserver);
        this.observe(owner, observer);
    }

    /**
     * 发布值，之后开始观察的观察者也会收到
     */
    public void forceValue(T value) {
        mForceNotifyFlag.set(true);
        if (Looper.getMainLooper() == Looper.myLooper()) {
            this.setValue(value);
        } else {
            super.postValue(value);
        }
    }

    /**
     * 恢复postValue状态；
     */
    public void observeFutureStatus() {
        this.mForceNotifyFlag.set(false);
    }


    private class ObserverWrap implements Observer<T> {

        private int mVersion;

        private final Observer<? super T> mObserver;

        public ObserverWrap(Observer<? super T> observer, int version) {
            this.mObserver = observer;
            this.mVersion = version;
        }

        @Override
        public void onChanged(T t) {
            if (mGlobalVersion.get() == mVersion && !FutureLiveData.this.mForceNotifyFlag.get()) {
                return;
            }

            mObserver.onChanged(t);
            mVersion = mGlobalVersion.get();
        }
    }
}
